package accesoBD;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Clase que representa la interacción de un técnico con la base de datos.
 * @version 1.2
 * @author Juan Manuel Rodríguez González
 */
public class QueryTecnico extends QueryUsuario {

    /**
     * Constructor de QueryTecnico. Al heredar de QueryUsuario hereda sus parámetros.
     * @param idUsuario String que contiene el id del usuario.
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public QueryTecnico(String idUsuario) throws SQLException, ClassNotFoundException {
        super(idUsuario);
    }

    /**
     * Devuelve los partes de los que es responsable el técnico.
     * @return Un objeto resultSet que contiene los partes obtenidos.
     * @throws SQLException
     */
    public ResultSet getPartesResposable() throws SQLException {
        return QueryTecnico.db.selectEscrito("select asi.id_parte from asigna asi,parte_incidencia pa where asi.id_usuario_tec=" + idUsuario + "and asi.fecha >= all (select asi2.fecha from asigna asi2 where asi.id_parte=asi2.id_parte) and pa.id_parte=asi.id_parte and pa.fecha_cierre is null");
    }

    /**
     * Devuelve los partes de los que es responsable el técnico.
     * @param idParte id del parte del cual se desea recuperar la información.
     * @return Un objeto resultSet que contiene los partes obtenidos.
     * @throws SQLException
     */
    public ResultSet getPartesInfo(int idParte) throws SQLException {
        return QueryTecnico.db.selectEscrito("select pa.descripcion_general, pa.estado, ap.id_aparato, ap.codigo_interno, ap.codigo_publico, ap.color, ap.fecha_compra, ap.garantia, ap.marca, ap.modelo, ub.planta, ub.pasillo, ub.sala from parte_incidencia pa, aparato ap, ubicacion ub where pa.id_aparato=ap.id_aparato and ub.id_ubicacion=ap.id_ubicacion and pa.id_parte=" + idParte);
    }

    /**
     * Devuelve los partes que ha completado el técnico.
     * @return Un objeto resultSet que contiene los partes finalizados.
     * @throws SQLException
     */
    public ResultSet getPartesCompletados() throws SQLException {
        return QueryTecnico.db.selectEscrito("select * from asigna a,parte_incidencia p where a.id_usuario_tec=" + idUsuario + " and p.id_parte=a.id_parte and p.estado=finalizado");
    }

    /**
     * Añadir una nueva incidencia a la base de datos.
     * @param parteReferencia id del parte al que está asociada la nueva incidencia.
     * @param diagnostico Descripción del diagnóstico de la incidencia.
     * @return un boolean informando del éxito de la inserción.
     * @throws SQLException
     */
    public boolean añadirIncidencia(int parteReferencia, String diagnostico) throws SQLException {

        PreparedStatement ps = QueryTecnico.db.getCon().prepareStatement("insert into incidencia values (incidencia_seq.nextval, ?, null)");
        ps.clearParameters();
        ps.setString(1, diagnostico);
        int s1 = ps.executeUpdate();

        ResultSet rs = QueryTecnico.db.selectEscrito("select incidencia_seq.currval from dual");
        rs.next();
        String idIncidencia = rs.getNString(1);

        ps = QueryTecnico.db.getCon().prepareStatement("insert into contiene (id_parte, id_incidencia) values (?,?)");
        ps.clearParameters();
        ps.setInt(1, parteReferencia);
        ps.setString(2, idIncidencia);
        int s2 = ps.executeUpdate();

        return (s1 > 0 && s2 > 0);
    }

    /**
     * Cierra un parte.
     * @param idParte identificador del parte de incidencia.
     * @return Un boolean informando del éxito de la actualización.
     * @throws SQLException
     */
    public boolean cerrarParte(String idParte) throws SQLException {

        PreparedStatement ps = QueryTecnico.db.getCon().prepareStatement("update parte_incidencia set estado='finalizado',fecha_cierre = sysdate where id_parte=?");
        ps.clearParameters();
        ps.setString(1, idParte);
        int s = ps.executeUpdate();

        return (s > 0);
    }

    /**
     * Añade una actuación sobre una incidencia.
     * @param idIncidencia identificador de la incidencia.
     * @param tiempoEstimado valor del tiempo estimado.
     * @param tiempoInvertido valor del tiempo invertido.
     * @param descripcion descripción de la actuación.
     * @param coste coste que ha supuesto la actuación.
     * @return Un boolean informando del éxito de la creación.
     * @throws SQLException
     */
    public boolean addActuacion(String idIncidencia, String tiempoEstimado, String tiempoInvertido, String descripcion, String coste) throws SQLException {
        PreparedStatement ps = QueryTecnico.db.getCon().prepareStatement("insert into actuacion values (actuacion_seq.nextval, ?, ?, 0, null, ?, ?)");
        ps.clearParameters();
        ps.setString(1, tiempoEstimado);
        ps.setString(2, tiempoInvertido);
        ps.setString(3, coste);
        ps.setString(4, descripcion);
        int s1 = ps.executeUpdate();

        ResultSet rs = QueryTecnico.db.selectEscrito("select actuacion_seq.currval from dual");
        rs.next();
        String idActuacion = rs.getString(1);

        ps = QueryTecnico.db.getCon().prepareStatement("insert into supone values (?, ?)");
        ps.clearParameters();
        ps.setString(1, idIncidencia);
        ps.setString(2, idActuacion);
        int s2 = ps.executeUpdate();

        return (s1 > 0 && s2 > 0);
    }

    /**
     * Obtiene los datos de una actuación.
     * @param idActuacion identificador único de la actuación.
     * @return Un objeto resultSet que contiene los datos de una actuación.
     * @throws SQLException
     */
    public ResultSet getActuacion(String idActuacion) throws SQLException {
        return QueryTecnico.db.selectEscrito("select * from actuacion where id_actuacion='" + idActuacion + "'");
    }

    /**
     * Actualiza una actuación sobre una incidencia.
     * @param idActuacion identificador de la actuación.
     * @param tiempoEstimado tiempo estimado.
     * @param tiempoInvertido tiempo invertido.
     * @param descripcion Descripción de la actuación.
     * @param coste coste de la actuación.
     * @return Un boolean informando del éxito de la actualización.
     * @throws SQLException
     */
    public boolean updateActuacion(String idActuacion, String tiempoEstimado, String tiempoInvertido, String descripcion, String coste) throws SQLException {
        PreparedStatement ps = QueryTecnico.db.getCon().prepareStatement("update actuacion set tiempo_estimado=?,tiempo_Invertido=?,coste=?,descripcion=? where id_actuacion=" + idActuacion);
        ps.clearParameters();
        ps.setString(1, tiempoEstimado);
        ps.setString(2, tiempoInvertido);
        ps.setString(3, coste);
        ps.setString(4, descripcion);
        int s = ps.executeUpdate();

        return (s > 0);
    }

    /**
     * Devuelve la descripcion de todas las áreas de trabajo.
     * @return Un objeto resultSet que contiene las descripciones de las áreas de trabajo.
     * @throws SQLException
     */
    public ResultSet getDescripcionArea() throws SQLException {
        return QueryTecnico.db.selectEscrito("select descripcion from area_de_trabajo");
    }

    /**
     * Devuelve el identificador único de una sala dado su nombre.
     * @param sala nombre de la sala.
     * @return Un objeto resultSet que contiene los partes obtenidos.
     * @throws SQLException
     */
    public ResultSet getIdSala(String sala) throws SQLException {
        return QueryTecnico.db.selectEscrito("select id_ubicacion from ubicacion where sala='" + sala + "'");
    }

    /**
     * Devuelve la descripción y el estado de un cierto parte de incidencia.
     * @param idParte identificador del parte de incidencia.
     * @return Un objeto resultSet que contiene los datos de los partes solicitados.
     * @throws SQLException
     */
    public ResultSet getDescEstadoParte(String idParte) throws SQLException {
        return QueryTecnico.db.selectEscrito("select descripcion_general, estado from parte_incidencia where id_parte='" + idParte + "'");
    }

    /**
     * Devuelve las incidencias den un parte.
     * @param idParte identificador del parte de incidencia.
     * @return Un objeto resultSet que contiene las incidencias.
     * @throws SQLException
     */
    public ResultSet getDiagnosticoDeParte(int idParte) throws SQLException {
        return QueryTecnico.db.selectEscrito("select inc.id_incidencia, inc.diagnostico from incidencia inc, contiene con where con.id_parte='" + idParte + "' and con.id_incidencia=inc.id_incidencia");
    }

    /**
     * Devuelve las actuaciones de una incidencia.
     * @param idIncidencia identificador de la incidencia.
     * @return Un objeto resultSet que contiene las actuaciones.
     * @throws SQLException
     */
    public int getActuacionDeIncidencia(int idIncidencia) throws SQLException {
        ResultSet rs = QueryTecnico.db.selectEscrito("select id_actuacion from supone where id_incidencia=" + idIncidencia);
        if (rs.next()) {
            return Integer.parseInt(rs.getString(1));
        } else {
            return -1;
        }
    }

    /**
     * Rechazar un parte de incidencia.
     * @param idParte Identificador del parte de incidencia.
     * @param idActuacion Identifdicador de la actuación.
     * @param motivo Descripción del motivo que provoca el rechazo.
     * @return un boolean informando de las actualizaciones.
     * @throws SQLException
     */
    public boolean rechazarParte(int idParte, int idActuacion, String motivo) throws SQLException {
        PreparedStatement ps = QueryTecnico.db.getCon().prepareStatement("update actuacion set motivo_rechazo=? where id_actuacion=" + idActuacion);
        ps.clearParameters();
        ps.setString(1, motivo);
        int s1 = ps.executeUpdate();

        ps = QueryTecnico.db.getCon().prepareStatement("update parte_incidencia set estado='rechazado' where id_parte=" + idParte);
        ps.clearParameters();
        int s2 = ps.executeUpdate();

        return (s1 > 0 && s2 > 0);
    }
}
